From d461f09e21a803512c6e6407eca83830722aa95d Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Tue, 26 Jul 2005 14:02:33 +0000 Subject: [PATCH] Start of code to persistent store connections when xenstored restarts Signed-off-by: Rusty Russel Signed-off-by: Christian Limpach --- tools/xenstore/xenstored_core.c | 55 ++++++++++++++++++++------ tools/xenstore/xenstored_domain.c | 65 ++++++++++++++++++++----------- tools/xenstore/xenstored_domain.h | 3 ++ 3 files changed, 88 insertions(+), 35 deletions(-) diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index 76ceb7dc70..e7c0c11d9d 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -1386,6 +1386,45 @@ void dump_connection(void) } #endif +static void setup_structure(void) +{ + struct xs_permissions perms = { .id = 0, .perms = XS_PERM_READ }; + char *root, *dir, *permfile; + + /* Create root directory, with permissions. */ + if (mkdir(xs_daemon_store(), 0750) != 0) { + if (errno != EEXIST) + barf_perror("Could not create root %s", + xs_daemon_store()); + return; + } + root = talloc_strdup(talloc_autofree_context(), "/"); + if (!set_perms(NULL, root, &perms, 1)) + barf_perror("Could not create permissions in root"); + + /* Create tool directory, with xenstored subdir. */ + dir = talloc_asprintf(root, "%s/%s", xs_daemon_store(), "tool"); + if (mkdir(dir, 0750) != 0) + barf_perror("Making dir %s", dir); + + permfile = talloc_strdup(root, "/tool"); + if (!set_perms(NULL, permfile, &perms, 1)) + barf_perror("Could not create permissions on %s", permfile); + + dir = talloc_asprintf(root, "%s/%s", dir, "xenstored"); + if (mkdir(dir, 0750) != 0) + barf_perror("Making dir %s", dir); + + permfile = talloc_strdup(root, "/tool/xenstored"); + if (!set_perms(NULL, permfile, &perms, 1)) + barf_perror("Could not create permissions on %s", permfile); + + talloc_free(root); + if (mkdir(xs_daemon_transactions(), 0750) != 0) + barf_perror("Could not create transaction dir %s", + xs_daemon_transactions()); +} + static struct option options[] = { { "no-fork", 0, NULL, 'N' }, { "verbose", 0, NULL, 'V' }, { "output-pid", 0, NULL, 'P' }, @@ -1461,22 +1500,14 @@ int main(int argc, char *argv[]) barf_perror("Could not listen on sockets"); /* If we're the first, create .perms file for root. */ - if (mkdir(xs_daemon_store(), 0750) == 0) { - struct xs_permissions perms; - char *root = talloc_strdup(talloc_autofree_context(), "/"); - - perms.id = 0; - perms.perms = XS_PERM_READ; - if (!set_perms(NULL, root, &perms, 1)) - barf_perror("Could not create permissions in root"); - talloc_free(root); - mkdir(xs_daemon_transactions(), 0750); - } else if (errno != EEXIST) - barf_perror("Could not create root %s", xs_daemon_store()); + setup_structure(); /* Listen to hypervisor. */ event_fd = domain_init(); + /* Restore existing connections. */ + restore_existing_connections(); + /* Debugging: daemonize() closes standard fds, so dup here. */ tmpout = dup(STDOUT_FILENO); if (dofork) { diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c index 31365594da..08130999cb 100644 --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -254,34 +254,21 @@ void handle_event(int event_fd) #endif } -/* domid, mfn, evtchn, path */ -bool do_introduce(struct connection *conn, struct buffered_data *in) +static struct domain *new_domain(void *context, domid_t domid, + unsigned long mfn, int port, + const char *path) { struct domain *domain; - char *vec[4]; - - if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec)) - return send_error(conn, EINVAL); - - if (conn->id != 0) - return send_error(conn, EACCES); - - if (!conn->can_write) - return send_error(conn, EROFS); - - /* Hang domain off "in" until we're finished. */ - domain = talloc(in, struct domain); - domain->domid = atoi(vec[0]); - domain->port = atoi(vec[2]); - if ((domain->port <= 0) || !is_valid_nodename(vec[3])) - return send_error(conn, EINVAL); - domain->path = talloc_strdup(domain, vec[3]); + domain = talloc(context, struct domain); + domain->domid = domid; + domain->port = port; + domain->path = talloc_strdup(domain, path); domain->page = xc_map_foreign_range(*xc_handle, domain->domid, getpagesize(), PROT_READ|PROT_WRITE, - atol(vec[1])); + mfn); if (!domain->page) - return send_error(conn, errno); + return NULL; list_add(&domain->list, &domains); talloc_set_destructor(domain, destroy_domain); @@ -292,11 +279,38 @@ bool do_introduce(struct connection *conn, struct buffered_data *in) /* Tell kernel we're interested in this event. */ if (ioctl(eventchn_fd, EVENTCHN_BIND, domain->port) != 0) - return send_error(conn, errno); + return NULL; domain->conn = new_connection(writechn, readchn); domain->conn->domain = domain; + return domain; +} +/* domid, mfn, evtchn, path */ +bool do_introduce(struct connection *conn, struct buffered_data *in) +{ + struct domain *domain; + char *vec[4]; + + if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec)) + return send_error(conn, EINVAL); + + if (conn->id != 0) + return send_error(conn, EACCES); + + if (!conn->can_write) + return send_error(conn, EROFS); + + /* Sanity check args. */ + if ((atoi(vec[2]) <= 0) || !is_valid_nodename(vec[3])) + return send_error(conn, EINVAL); + /* Hang domain off "in" until we're finished. */ + domain = new_domain(in, atoi(vec[0]), atol(vec[1]), atol(vec[2]), + vec[3]); + if (!domain) + return send_error(conn, errno); + + /* Now domain belongs to its connection. */ talloc_steal(domain->conn, domain); return send_ack(conn, XS_INTRODUCE); @@ -375,6 +389,11 @@ const char *get_implicit_path(const struct connection *conn) return conn->domain->path; } +/* Restore existing connections. */ +void restore_existing_connections(void) +{ +} + /* Returns the event channel handle. */ int domain_init(void) { diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h index 74dc34e8e5..ccdf1dbf60 100644 --- a/tools/xenstore/xenstored_domain.h +++ b/tools/xenstore/xenstored_domain.h @@ -37,4 +37,7 @@ int domain_init(void); /* Returns the implicit path of a connection (only domains have this) */ const char *get_implicit_path(const struct connection *conn); +/* Read existing connection information from store. */ +void restore_existing_connections(void); + #endif /* _XENSTORED_DOMAIN_H */ -- 2.30.2